Release 10.1A: OpenEdge Development:
Web Services


Using a client-created SOAP request header

This example shows how you might create a SOAP header internally to use as an initial SOAP request header, as opposed to recycling a header previously received in a SOAP response message (described in previous examples). This is an example of the header created by the client for the Web service:

SOAP request header created entirely by the client
<SOAP-ENV:Envelope 
        . . . 
        <SOAP-ENV:Header> 
                <ns0:AuthHeader xmlns:ns0="http://ServiceHost/SOAPHeader"> 
                        <ns0:UserName>Scott</ns0:UserName> 
                        <ns0:Password>Administrator</ns0:Password> 
                </ns0:AuthHeader> 
        </SOAP-ENV:Header> 
        . . . 
</SOAP-ENV:Envelope> 

The client creates a header very similar to the headers described in the previous examples. The <UserName> and <Password> elements, in this case, provide user authentication for each Web service request. The Web service requires this authentication for every Web service request.

The following is the mainline of a procedure that invokes the Web service to create the initial SOAP request header containing a username and password node. This code:

  1. Defines several mainline variables, including handles to access the global SOAP header (g_header) created for requests and its XML, and variables to hold the username (cUsername) and password (cPassword) values.
  2. Builds the global request header used for all requests (see the "Procedure to create a SOAP request header" section).
  3. Registers the request header (ReqHandler) handler after connecting to the Web service and instantiating the HeaderSoap port type procedure object.
  4. Runs the HelloMyWorld procedure to invoke a Web service operation, passing back the global SOAP request header created by the client (see the "Request header handler for passing a globally-created header object" section).
  5. Cleans up the global objects maintained in its context and disconnects from the Web service. Note that one of the objects it deletes is the global SOAP request header create by the client.
  6. Invoking a request that creates a SOAP request header on the client
    /* 
     * SOAPHeader3.p 
     * 
     * Calls a ficticious web service, passes it a username and password through 
     * a SOAP message request header, and gets back a string. 
     *  
     * The Web service has only one service and port available. 
     */ 
    /* Define local variables */ /*1*/  
    DEFINE VARIABLE hWebSrvc      AS HANDLE. 
    DEFINE VARIABLE hPortType     AS HANDLE. 
    DEFINE VARIABLE cUsername     AS CHARACTER INIT "Scott".  
    DEFINE VARIABLE cPassword     AS CHARACTER INIT "Administrator" . 
    DEFINE VARIABLE cResponse     AS CHARACTER FORMAT "x(72)". 
    DEFINE VARIABLE hXdoc         AS HANDLE. 
    DEFINE VARIABLE hXnoderef1    AS HANDLE. 
    DEFINE VARIABLE hXnoderef2    AS HANDLE. 
    DEFINE VARIABLE hXAttribute   AS HANDLE. 
    DEFINE VARIABLE hXtext        AS HANDLE. 
    DEFINE VARIABLE g_header      AS HANDLE. 
    /*2*/  
    /* Build global SOAP request header */ 
    RUN BuildRequestHeader (OUTPUT g_header).  
    /* Create the Web service server object */ 
    CREATE SERVER hWebSrvc. 
    /* Connect to the WS */ 
    hWebSrvc:CONNECT("-WSDL 
    http://ServiceHost/SOAPHeader/HeaderExample.asmx?wsdl"). 
    /* Get the method, set the port type */ 
    RUN HeaderSoap SET hPortType ON hWebSrvc. 
    /*3*/  
    /* Associate the request callback with the port type */ 
    hPortType:SET-CALLBACK-PROCEDURE("REQUEST-HEADER", "ReqHandler").  
    /*4*/  
    /* Invoke the web service and display the results */ 
    RUN HellowMyWorld IN hPortType (OUTPUT cResponse).  
    DISPLAY cResponse LABEL "WS Response" WITH FRAME aaa. 
    /*5*/  
    DELETE OBJECT g_header.  
    DELETE OBJECT hPortType. 
    hWebSrvc:DISCONNECT(). 
    DELETE OBJECT hWebSrvc. 
    /**************** Internal Procedures ****************/ 
    

Procedure to create a SOAP request header

This is the procedure (BuildRequestHeader) that creates the global SOAP request header that the client sends in all requests to the Web service:

Procedure to create a SOAP request header (start)
PROCEDURE BuildRequestHeader: /*1*/  
    /* Define procedure parameter */ 
    DEFINE OUTPUT PARAMETER hHeader AS HANDLE. 
    /*2*/  
    DEFINE VARIABLE hHeaderEntryref AS HANDLE. 
    DEFINE VARIABLE ClientNS AS CHARACTER  
        INIT "http://ServiceHost/SOAPHeader". 
    /*3*/  
    /* Create SOAP header and server objects */ 
    CREATE SOAP-HEADER hHeader. 
    CREATE SOAP-HEADER-ENTRYREF hHeaderEntryref. 
    /*4*/  
    /* Create x-doc objects to build header */ 
    CREATE X-DOCUMENT hXdoc. 
    CREATE X-NODEREF hXAttribute. 
    CREATE X-NODEREF hXnoderef1. 
    CREATE X-NODEREF hXnoderef2. 
    CREATE X-NODEREF hXtext. 

This code:

  1. Defines a single output parameter to return the global SOAP header object that it creates to the client mainline context.
  2. Defines a handle variable (hHeaderEntryref) to reference the SOAP header entryref object, and a variable (ClientNS) that specifies the namespace for the SOAP header entry that it creates.
  3. Creates the global SOAP header object that references the XML for the header using the CREATE SOAP-HEADER statement, and creates the SOAP header entryref object that references the XML for the header entry using the CREATE SOAP-HEADER-ENTRYREF statement.
  4. Creates the x-document and x-noderef objects required to build the XML to be added as the header entry for the global SOAP header.
  5. Adds a header entry to the newly-created SOAP header object, referenced by the hHeaderEntryref object, using the ADD-HEADER-ENTRY( ) method.
  6. Creates the root node (<AuthHeader> element) for the header entry in the working x-document object.
  7. Note: The namespace attribute specifying http://www.w3.org/2000/xmlns/ is a requirement of the DOM. For more information, see the information on XML support in OpenEdge Development: Programming Interfaces .

  8. Creates the <UserName> element as a child node of the header entry.
  9. Creates the <Password> element as a second child node of the header entry.
  10. Assigns the header entry in the global SOAP header object to the XML for the <AuthHeader> element of the x-document object using the SET-NODE( ) method.
  11. Procedure to create a SOAP request header (continuation) 
        /*5*/  
        /* Create the header entry */ 
        hHeader:ADD-HEADER-ENTRY(hHeaderEntryref). 
        /*6*/  
        /* Create the header namespace data */ 
        hXdoc:CREATE-NODE-NAMESPACE(hXnoderef1, ClientNS,  
                                    "AuthHeader", "ELEMENT"). 
        hXdoc:CREATE-NODE-NAMESPACE(hXAttribute, 
                                    "http://www.w3.org/2000/xmlns/",  
                                    "xmlns", "ATTRIBUTE"). 
        hXAttribute:NODE-VALUE = ClientNS. 
        hXnoderef1:SET-ATTRIBUTE-NODE(hXAttribute). 
        hXdoc:INSERT-BEFORE(hXnoderef1, ?). 
        /*7*/  
        /* Create the Username/Password data */ 
        hXdoc:CREATE-NODE-NAMESPACE(hXnoderef2, ClientNS,  
                                    "UserName", "ELEMENT"). 
        hXnoderef1:APPEND-CHILD(hXnoderef2). 
        hXdoc:CREATE-NODE(hXtext,"","text"). 
        hXnoderef2:APPEND-CHILD(hXtext). 
        hXtext:NODE-VALUE = cUsername. 
        /*8*/  
        hXdoc:CREATE-NODE-NAMESPACE(hXnoderef2, ClientNS,  
                                    "Password", "ELEMENT"). 
        hXnoderef1:APPEND-CHILD(hXnoderef2). 
        hXdoc:CREATE-NODE(hXtext, "", "text"). 
        hXnoderef2:APPEND-CHILD(hXtext). 
        hXtext:NODE-VALUE = cPassword. 
        /*9*/  
        /* Fill the header entry using a deep copy */ 
        hHeaderEntryref:SET-NODE(hXnoderef1). 
    

    Procedure to create a SOAP request header (end) 
        /*9*/  
        /* Fill the header entry using a deep copy */ 
        hHeaderEntryref:SET-NODE(hXnoderef1). 
        /*10*/  
        /* Procedure/header cleanup */  
        DELETE OBJECT hXdoc. 
        DELETE OBJECT hXAttribute. 
        DELETE OBJECT hXnoderef1. 
        DELETE OBJECT hXnoderef2. 
        DELETE OBJECT hXtext. 
        DELETE OBJECT hHeaderEntryref. 
    END PROCEDURE. 
    

  12. Cleans up by deleting all the helper objects created in the procedure before returning to the client mainline.
Request header handler for passing a globally-created header object

This is the SOAP request header handler (ReqHandler) that passes the global SOAP request header created by the client and the Web service for each request:

Request header handler passing a client-created SOAP request header
PROCEDURE ReqHandler: /*1*/  
    /* Define procedure parameters */ 
    DEFINE OUTPUT PARAMETER hHeader    AS HANDLE. 
    DEFINE INPUT  PARAMETER cNamespace AS CHARACTER. 
    DEFINE INPUT  PARAMETER cLocalNS   AS CHARACTER. 
    DEFINE OUTPUT PARAMETER lDeleteOnDone AS LOGICAL. 
    /*2*/  
    /* Pass in global header reused for every request */ 
    hHeader = g_header. 
    lDeleteOnDone = FALSE. 
END PROCEDURE. 

This code:

  1. Sends the SOAP request header for the HelloMyWorld request (and any subsequent request).
  2. Passes the global SOAP header the request header output parameter and ensures that it is not deleted until the client mainline has finished with it.

Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095